#include "ds18b20.h"

DS18B20_T    ds18b20_t; 
extern INT8U uart_buffer[UART_BUFF_MAX];
/*****************************************************************************
 �� �     ��	:ds18b20_init()
 ��������  : DS18B20������ʼ��
 �����             : ��			
 �������  : ��
 �� �� ֵ: ��
 �޸��    ʷ 	 :
    1.�     	     �	 : 2019��03��03��
        �     	     �	 : ΢Ц����
        �޸�    ���	 : ����
*****************************************************************************/
void ds18b20_init(void)
{
    ds18b20_t.reset_result   = 0;
    ds18b20_t.state          = TEMP_CHANGING;
    ds18b20_t.read_temp_step = 1;
}


/*****************************************************************************
 �� �     ��	:ds18b20_write_byte
 ��������  : ��DS18B20д��һ���ֽ�
 �����             : ��			
 �������  : ��
 �� �� ֵ: ��
 �޸��    ʷ 	 :
    1.�     	     �	 : 2019��03��03��
        �     	     �	 : ΢Ц����
        �޸�    ���	 : ����
*****************************************************************************/
void ds18b20_write_byte(INT8U _data)
{
    INT8U ds18b20_delay_us, i;
    GLOBAL_INTERRUPT_DISABLE();
    for(i=0; i<8; i++)
    {
            CLR_DS18B20_BUS();                 
            ds18b20_delay_us ++;
            if(1 ==(_data & 0x01))         
            {
                SET_DS18B20_BUS();
            }
            else
            {
                CLR_DS18B20_BUS();
            }     
            ds18b20_delay_us = 6;
            while(ds18b20_delay_us --);   
            SET_DS18B20_BUS();              
            _data >>= 1;
    }
    GLOBAL_INTERRUPT_ENABLE();
}


/*****************************************************************************
 �� �     ��	:ds18b20_read_byte
 ��������  : ��DS18B20��ȡһ���ֽ�
 �����             : ��			
 �������  : ��
 �� �� ֵ: ��ȡ���
 �޸��    ʷ 	 :
    1.�     	     �	 : 2019��03��03��
        �     	     �	 : ΢Ц����
        �޸�    ���	 : ����
*****************************************************************************/
INT8U ds18b20_read_byte(void)
{
    INT8U byte, Bit;
    INT8U ds18b20_delay_us, i;
    GLOBAL_INTERRUPT_DISABLE();
    for(i=8; i>0; i--)
    {
        CLR_DS18B20_BUS();
        ds18b20_delay_us ++;
        
        SET_DS18B20_BUS();
        ds18b20_delay_us ++;
        ds18b20_delay_us ++;
                    
        if(GET_DS18B20_BUS())
        {
            Bit = 1;
        } 
        else
        {
            Bit = 0;
        }
        
        byte = (byte >> 1) | (Bit << 7);
        ds18b20_delay_us = 4;
        while(ds18b20_delay_us --);
    }
    GLOBAL_INTERRUPT_ENABLE();
    return byte;
}


/*****************************************************************************
 �� �     ��	:ds18b20_temp_process
 ��������  : ��ȡ�¶�ת�����
 �����             : ��			
 �������  : ��
 �� �� ֵ: ��
 �޸��    ʷ 	 :
    1.�     	     �	 : 2019��03��03��
        �     	     �	 : ΢Ц����
        �޸�    ���	 : ����
*****************************************************************************/
void ds18b20_temp_process(void)
{
        INT8U temp_h, temp_l;
        INT8U ds18b20_delay_us;
    
        switch(ds18b20_t.read_temp_step)
        {
         case 0:
         {
            if(0 == ds18b20_t.delay_ms)
            {
                CLR_DS18B20_BUS();
                ds18b20_delay_us = 70;
                while(ds18b20_delay_us --);
        
                SET_DS18B20_BUS();
                while(GET_DS18B20_BUS())
                {
                    ds18b20_delay_us ++;
                    if(ds18b20_delay_us > 300)
                    {
                        ds18b20_t.reset_result   = 0;
                            return;
                    }
                }
        
                if(TEMP_CHANGING == ds18b20_t.state)
                {
                   ds18b20_t.read_temp_step = 1;
                }
                else if(TEMP_READING == ds18b20_t.state)
                {
                   ds18b20_t.read_temp_step = 2;
                }
        
                ds18b20_t.reset_result = 1;
                ds18b20_t.delay_ms     = 1;        
                }
            }
            break;
            case 1:
            {   if(0 == ds18b20_t.reset_result)
                {
                    ds18b20_t.read_temp_step = 0;
                    ds18b20_t.state = TEMP_CHANGING;
                    break;
                }
                else if(1 == ds18b20_t.reset_result && 0 == ds18b20_t.delay_ms)
                {
                    ds18b20_write_byte(0xcc);
                    ds18b20_write_byte(0x44);
                    ds18b20_t.read_temp_step = 2;
                    ds18b20_t.state          = NONE;
                    ds18b20_t.reset_result   = 0;
                    ds18b20_t.delay_ms       = 100; 
                }
            
            }
            break;
            case 2:
            {
                if(0 == ds18b20_t.reset_result)
                {
                    ds18b20_t.read_temp_step = 0;
                    ds18b20_t.state = TEMP_READING;
                    break;
                }
                else if(1 == ds18b20_t.reset_result && 0 == ds18b20_t.delay_ms)
                {
                    ds18b20_write_byte(0xcc);
                    ds18b20_write_byte(0xbe);
                    temp_l = ds18b20_read_byte(); 
                    temp_h = ds18b20_read_byte();    
                    ds18b20_t.temp = (temp_h << 8) | temp_l;                                 
                    ds18b20_t.read_temp_step = 3;
                    ds18b20_t.state          = NONE;
                    ds18b20_t.reset_result   = 0;
                }
            }
            break;
            case 3:
            {         
                ds18b20_t.read_temp_step ++;
                ds18b20_t.delay_ms       = 1000;
                if(GET_Bit(ds18b20_t.temp, 11))
                {
                    ds18b20_t.temp = (~ds18b20_t.temp + 1);
                }
            }
            break;
            case 4:
            {         
                if(0 < ds18b20_t.delay_ms )
                {
                   return;
                }
                ds18b20_init();
            }
            break;
            default:
                break;
        }
    
    return;
}

